# -*- coding: utf-8 -*-
"""
彩票数据爬虫模块
负责从官方网站获取七星彩历史开奖数据
"""

import requests
import time
import re
from datetime import datetime, timedelta
from bs4 import BeautifulSoup
from .database import DatabaseManager
import logging

logger = logging.getLogger(__name__)

class LotteryCrawler:
    def __init__(self, db_manager=None):
        self.db = db_manager or DatabaseManager()
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
        })
        
        # API URLs
        self.qxc_batch_url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry'
        self.qxc_single_url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry'
        
    def crawl_qxc_data(self, start_period=None, end_period=None, max_periods=100):
        """爬取七星彩数据"""
        try:
            if start_period and end_period:
                logger.info(f"开始爬取七星彩数据，期号范围: {start_period} - {end_period}")
                success_count = self.fetch_qxc_batch_data(start_period, end_period)
            else:
                success_count = self.crawl_latest_data(max_periods)
            
            logger.info(f"七星彩数据爬取完成，成功获取 {success_count} 期数据")
            return success_count
        except Exception as e:
            logger.error(f"爬取七星彩数据时发生错误: {e}")
            return 0
    
    def fetch_qxc_batch_data(self, start_period, end_period):
        """批量获取七星彩数据（使用官方API）"""
        try:
            # 使用官方API获取数据
            api_url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry'
            
            # 设置API请求头
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': 'application/json, text/plain, */*',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            }
            
            success_count = 0
            start_num = int(start_period)
            end_num = int(end_period)
            target_periods = set(str(i) for i in range(start_num, end_num + 1))
            
            # 计算需要的数据量，使用更大的pageSize提高效率
            needed_count = end_num - start_num + 1
            page_size = min(100, max(30, needed_count))  # 根据需要调整pageSize，最大100
            
            page_no = 1
            max_pages = 10  # 最多查询10页，避免无限循环
            
            logger.info(f"开始批量获取七星彩数据，期号范围: {start_period} - {end_period}，需要 {needed_count} 期数据")
            
            while target_periods and page_no <= max_pages:
                # API请求参数
                params = {
                    'gameNo': '04',  # 七星彩游戏编号（修正：04才是七星彩，85是超级大乐透）
                    'provinceId': 0,
                    'pageSize': page_size,
                    'isVerify': 1,
                    'pageNo': page_no
                }
                
                response = self.session.get(api_url, params=params, headers=headers, timeout=10)
                
                if response.status_code != 200:
                    logger.error(f"API请求失败，状态码: {response.status_code}")
                    break
                
                data = response.json()
                
                if not data.get('success') or not data.get('value', {}).get('list'):
                    logger.error(f"第{page_no}页API返回数据格式错误")
                    break
                
                current_page_data = data['value']['list']
                logger.info(f"第{page_no}页获取到 {len(current_page_data)} 条数据")
                
                # 处理当前页的数据
                page_success = 0
                for item in current_page_data:
                    period = item.get('lotteryDrawNum')
                    
                    if period in target_periods:
                        # 解析开奖号码
                        result_str = item.get('lotteryDrawResult', '')
                        numbers = self.parse_api_numbers(result_str)
                        draw_date = item.get('lotteryDrawTime', '')
                        
                        if numbers and len(numbers) == 7:
                            if self.db.insert_qxc_data(period, draw_date, numbers):
                                success_count += 1
                                page_success += 1
                                target_periods.remove(period)
                            else:
                                logger.error(f"插入七星彩数据失败: {period}")
                        else:
                            logger.warning(f"解析号码失败: {period} - {result_str}")
                
                logger.info(f"第{page_no}页成功处理 {page_success} 条数据，剩余需要 {len(target_periods)} 期")
                
                # 如果当前页没有找到任何目标期号，可能已经超出范围
                if page_success == 0:
                    # 检查当前页的期号范围
                    if current_page_data:
                        min_period = min(int(item.get('lotteryDrawNum', 0)) for item in current_page_data)
                        if min_period < start_num:
                            logger.info(f"第{page_no}页期号范围已超出目标范围，停止查询")
                            break
                
                page_no += 1
            
            logger.info(f"批量获取完成，成功获取 {success_count} 期数据")
            
            # 如果还有未获取到的期号，记录日志
            if target_periods:
                logger.warning(f"仍有 {len(target_periods)} 期数据未获取到: {sorted(target_periods)[:10]}...")
            
            return success_count
                    
        except Exception as e:
            logger.error(f"批量获取数据时发生错误: {e}")
            return 0
    
    def fetch_qxc_period_data(self, period):
        """获取指定期号的七星彩数据（使用官方API）"""
        try:
            # 使用官方API获取数据
            api_url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry'
            
            # 设置API请求头
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': 'application/json, text/plain, */*',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            }
            
            # API请求参数
            params = {
                'gameNo': '04',  # 七星彩游戏编号（修正：04才是七星彩，85是超级大乐透）
                'provinceId': 0,
                'pageSize': 30,
                'isVerify': 1,
                'pageNo': 1
            }
            
            response = self.session.get(api_url, params=params, headers=headers, timeout=10)
            
            if response.status_code == 200:
                data = response.json()
                if data.get('success') and data.get('value', {}).get('list'):
                    for item in data['value']['list']:
                        if item.get('lotteryDrawNum') == str(period):
                            result_str = item.get('lotteryDrawResult', '')
                            numbers = self.parse_api_numbers(result_str)
                            if numbers and len(numbers) == 7:
                                return {
                                    'period': period,
                                    'numbers': numbers,
                                    'date': item.get('lotteryDrawTime', '')
                                }
            else:
                logger.error(f"API请求失败，状态码: {response.status_code}")
                return None

        except Exception as e:
            logger.error(f"获取期号 {period} 数据时发生错误: {e}")
            return None
    
    def parse_api_numbers(self, result_str):
        """解析API返回的开奖号码字符串
        
        七星彩开奖结果格式：7个数字用空格分隔
        前6位：0-9 的单位数（API可能返回两位数格式如"01"，但实际值必须是0-9）
        第7位：00-14 的两位数
        """
        try:
            if not result_str:
                return None
            
            # 按空格分割开奖号码
            parts = result_str.strip().split()
            
            if len(parts) != 7:
                logger.warning(f"开奖号码分割后长度不正确，期望7个数字，实际得到{len(parts)}个: {parts}")
                return None
            
            numbers = []
            for i, part in enumerate(parts):
                try:
                    num = int(part)
                    
                    # 验证数字范围
                    if i < 6:  # 前6位：0-9 的单位数
                        if not (0 <= num <= 9):
                            logger.warning(f"第{i+1}位数字超出范围(0-9): {num}，API返回的数据可能不符合七星彩规则")
                            return None
                    else:  # 第7位：00-14
                        if not (0 <= num <= 14):
                            logger.warning(f"第7位数字超出范围(00-14): {num}")
                            return None
                    
                    numbers.append(num)
                    
                except ValueError:
                    logger.error(f"无法将'{part}'转换为数字")
                    return None
            
            return numbers
            
        except Exception as e:
            logger.error(f"解析开奖号码时发生错误: {e}")
            return None
    
    def crawl_latest_data(self, max_periods=100):
        """爬取最新的七星彩数据"""
        try:
            # 获取最新期号
            latest_period = self.get_latest_qxc_period()
            if not latest_period:
                logger.error("无法获取最新期号")
                return 0
            
            # 计算起始期号
            start_period = max(1, latest_period - max_periods + 1)
            
            return self.fetch_qxc_batch_data(start_period, latest_period)
            
        except Exception as e:
            logger.error(f"爬取最新数据时发生错误: {e}")
            return 0
    
    def force_update_recent_data(self, max_periods=100):
        """强制更新最近几期的七星彩数据"""
        logger.info(f"强制更新最近 {max_periods} 期数据")
        return self.crawl_latest_data(max_periods)
    
    def get_latest_qxc_period(self):
        """获取最新的七星彩期号"""
        try:
            api_url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry'
            
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': 'application/json, text/plain, */*',
            }
            
            params = {
                'gameNo': '04',
                'provinceId': 0,
                'pageSize': 1,
                'isVerify': 1,
                'pageNo': 1
            }
            
            response = self.session.get(api_url, params=params, headers=headers, timeout=10)
            
            if response.status_code == 200:
                data = response.json()
                if data.get('success') and data.get('value', {}).get('list'):
                    latest_item = data['value']['list'][0]
                    return int(latest_item.get('lotteryDrawNum', 0))
            
            logger.error("无法获取最新期号")
            return None
            
        except Exception as e:
            logger.error(f"获取最新期号时发生错误: {e}")
            return None
    
    def test_connection(self):
        """测试网络连接"""
        try:
            response = self.session.get('https://www.sporttery.cn', timeout=5)
            if response.status_code == 200:
                logger.info("网络连接正常")
                return True
            else:
                logger.warning(f"网络连接异常，状态码: {response.status_code}")
                return False
        except Exception as e:
            logger.error(f"网络连接测试失败: {e}")
            return False